#include "tools/vector_eigen_converter.h"
#include <Eigen/Dense>
#include <vector>

namespace  ldl_eigen
{
Eigen::MatrixXf VectorEigenConverter::to_eigen_matrix(const std::vector<std::vector<double>>& vec) {
    if (vec.empty()) return Eigen::MatrixXf(); // 处理空向量

    size_t rows = vec.size();
    size_t cols = vec[0].size();

    Eigen::MatrixXf mat(rows, cols);

    for (size_t i = 0; i < rows; ++i) {
        if (vec[i].size() != cols) {
            throw std::runtime_error("Inconsistent row sizes in input vector");
        }
        for (size_t j = 0; j < cols; ++j) {
            mat(i, j) = vec[i][j];
        }
    }

    return mat;
}

Eigen::VectorXf VectorEigenConverter::to_eigen_vector(const std::vector<double>& vec) {
    Eigen::VectorXf eigen_vec(vec.size());
    std::copy(vec.begin(), vec.end(), eigen_vec.data());
    return eigen_vec;
}

std::vector<std::vector<double>> VectorEigenConverter::to_vector_2d(const Eigen::MatrixXf& mat) {
    std::vector<std::vector<double>> vec;
    vec.reserve(mat.rows());

    for (int i = 0; i < mat.rows(); ++i) {
        Eigen::VectorXf row = mat.row(i);
        std::vector<double> row_vec(row.data(), row.data() + row.size());
        vec.push_back(row_vec);
    }

    return vec;
}

std::vector<double> VectorEigenConverter::to_vector_1d(const Eigen::VectorXf& vec) {
    // Create a std::vector with the same size as the Eigen vector
    std::vector<double> result(vec.size());
    
    // Copy elements from Eigen vector to std::vector
    for (int i = 0; i < vec.size(); ++i) {
        result[i] = vec(i);
    }
    
    return result;
}

}